#include <iostream>
using namespace std;

struct Pos{
    int x, y;

    Pos() : x(0), y(0) {}
    Pos(int a, int b) : x(a), y(b) {}

    bool operator==(const Pos& other) const {
        return (this->x == other.x) && (this->y == other.y);
    }
    Pos operator+(const Pos& other) const {
        Pos res;
        res.x = this->x + other.x;
        res.y = this->y + other.y;
        return res;
    }
};

Pos leftdir(-1, 0), rightdir(1, 0), updir(0, -1), downdir(0, 1);
Pos direction(rightdir);
void changedir(){
    if(direction == leftdir){
        direction = updir;
    } else if(direction == updir){
        direction = rightdir;
    } else if(direction == rightdir){
        direction = downdir;
    } else {
        direction = leftdir;
    }
}

int main(){
    int n;
    cin >> n;
    int matrix[n][n], num = 1, start;
    if(n % 2) start = n / 2;
    else start = n / 2 - 1;
    
    // ****** 此次开始用ai完成 *******
    // 从中心开始填充
    Pos current(start, start);
    matrix[current.y][current.x] = num++;
    
    int steps = 1;
    
    while(num <= n * n){
        // 每个方向走steps步
        for(int step = 0; step < 2; step++){
            for(int i = 0; i < steps && num <= n * n; i++){
                current = current + direction;
                if(current.x >= 0 && current.x < n && current.y >= 0 && current.y < n){
                    matrix[current.y][current.x] = num++;
                }
            }
            changedir(); // 改变方向
        }
        steps++; // 每两个方向后步数增加
    }
    
    // 输出矩阵
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}